package rothag.views.gamestep.feed;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import rothag.models.desastres.Desastre;
import rothag.controller.MainController;
import rothag.enums.TypeDes;
import rothag.graphics.*;

import rothag.views.JButtonBase;
import rothag.views.gamestep.GameStepJPanelBase;
import rothag.listener.*;
import rothag.models.desastres.Invasion;
import rothag.models.desastres.Peste;
import rothag.models.desastres.Revolte;
import rothag.models.desastres.Secheresse;
import rothag.models.developpement.Agriculture;
import rothag.models.developpement.Developpement;
import rothag.models.developpement.Maconnerie;

/**
 *
 * @author Gaetan
 */
public class NourrirJPanel extends GameStepJPanelBase implements ActionListener, DesListener, DesastreListener {

    public static final int MODE_SELECTION = 1;
    public static final int MODE_INFOS_ALIMENTATION = 2;
    private int mode;// 1 : sélection, 2 : infos alimentation
    private int hauteurLabel;
    private int nbOuvrier;
    private int nbNourriture;
    private int nbVille;
    private int nbChoix;
    private int nbOuvrierSel;
    private int nbNourritureSel;
    private int nbVillesFamine;
    private Desastre desastre;
    private JButtonBase etapeSuivante;
    private JLabel infosLabel;
    private JLabel ouvrierLabel;
    private JLabel nourritureLabel;
    private JLabel instructionLabel;
    private JLabel resOuvLabel;
    private JLabel resFoodLabel;
    private JLabel desastreLabel;
    private JLabel famineLabel;
    private JLabel desastreImagePeste;
    private JLabel desastreImageInvasion;
    private JLabel desastreImageSecheresse;
    private JLabel desastreImageRevolte;
    private JLabel desastreImageVide;
    private ArrayList<SelectionDeJPanel> selectionDeListe;
    private int nbOuvrierSup;
    private int nbNourritureSup;

    public NourrirJPanel(MainController controller) {
        super(controller);

        controller.addDesListener(this);
        controller.addDesastreListener(this);

        hauteurLabel = 20;
        Font font = GraphicsHelper.getFont(13, null);

        // Instructions
        instructionLabel = new JLabel("Choisissez entre des ouvriers ou de la nourriture.");
        instructionLabel.setFont(font);
        instructionLabel.setForeground(Color.white);
        instructionLabel.setBounds(50, GraphicsParameters.bigFrameBottomY - hauteurLabel, largeur - 50, hauteurLabel);
        add(instructionLabel);

        infosLabel = new JLabel();
        infosLabel.setFont(font);
        infosLabel.setForeground(Color.white);
        infosLabel.setBounds(50, GraphicsParameters.smallFrameTopY, largeur - 250, hauteurLabel);
        add(infosLabel);

        // Images
        ImageIcon image = GraphicsHelper.getImageIcon(GraphicsParameters.pathResOuv, this);
        if (image.getIconHeight() == -1) {
            GraphicsHelper.afficherErreur("Erreur", "Erreur lors de l'ouverture du fichier image : " + GraphicsParameters.pathResOuv, this).setVisible(true);
            System.exit(1);
        }
        resOuvLabel = new JLabel(image);
        resOuvLabel.setBounds(150, GraphicsParameters.smallFrameTopY + 50, image.getIconWidth(), image.getIconHeight());
        add(resOuvLabel);

        image = GraphicsHelper.getImageIcon(GraphicsParameters.pathResFood, this);
        if (image.getIconHeight() == -1) {
            GraphicsHelper.afficherErreur("Erreur", "Erreur lors de l'ouverture du fichier image : " + GraphicsParameters.pathResFood, this).setVisible(true);
            System.exit(1);
        }
        resFoodLabel = new JLabel(image);
        resFoodLabel.setBounds(250, GraphicsParameters.smallFrameTopY + 50, image.getIconWidth(), image.getIconHeight());
        add(resFoodLabel);

        // Valeurs
        ouvrierLabel = new JLabel("0");
        ouvrierLabel.setFont(font);
        ouvrierLabel.setForeground(Color.white);
        ouvrierLabel.setBounds(200, GraphicsParameters.smallFrameTopY + 60, largeur - 50, hauteurLabel);
        add(ouvrierLabel);

        nourritureLabel = new JLabel("0");
        nourritureLabel.setFont(font);
        nourritureLabel.setForeground(Color.white);
        nourritureLabel.setBounds(300, GraphicsParameters.smallFrameTopY + 60, largeur - 50, hauteurLabel);
        add(nourritureLabel);

        etapeSuivante = new JButtonBase("Etape suivante");
        etapeSuivante.setBounds(550, GraphicsParameters.smallFrameTopY + 60, 120, 40);
        etapeSuivante.addActionListener(this);
        GraphicsHelper.setCursorHand(etapeSuivante);
        add(etapeSuivante);

        image = GraphicsHelper.getImageIcon(GraphicsParameters.pathDesastrePeste, this);
        if (image.getIconHeight() == -1) {
            GraphicsHelper.afficherErreur("Erreur", "Erreur lors de l'ouverture du fichier image : " + GraphicsParameters.pathDesastrePeste, this).setVisible(true);
            System.exit(1);
        }
        desastreImagePeste = new JLabel(image);
        desastreImagePeste.setBounds(33, 182, image.getIconWidth(), image.getIconHeight());
        add(desastreImagePeste);

        image = GraphicsHelper.getImageIcon(GraphicsParameters.pathDesastreInvasion, this);
        if (image.getIconHeight() == -1) {
            GraphicsHelper.afficherErreur("Erreur", "Erreur lors de l'ouverture du fichier image : " + GraphicsParameters.pathDesastreInvasion, this).setVisible(true);
            System.exit(1);
        }
        desastreImageInvasion = new JLabel(image);
        desastreImageInvasion.setBounds(33, 182, image.getIconWidth(), image.getIconHeight());
        add(desastreImageInvasion);

        image = GraphicsHelper.getImageIcon(GraphicsParameters.pathDesastreSecheresse, this);
        if (image.getIconHeight() == -1) {
            GraphicsHelper.afficherErreur("Erreur", "Erreur lors de l'ouverture du fichier image : " + GraphicsParameters.pathDesastreSecheresse, this).setVisible(true);
            System.exit(1);
        }
        desastreImageSecheresse = new JLabel(image);
        desastreImageSecheresse.setBounds(33, 182, image.getIconWidth(), image.getIconHeight());
        add(desastreImageSecheresse);

        image = GraphicsHelper.getImageIcon(GraphicsParameters.pathDesastreRevolte, this);
        if (image.getIconHeight() == -1) {
            GraphicsHelper.afficherErreur("Erreur", "Erreur lors de l'ouverture du fichier image : " + GraphicsParameters.pathDesastreRevolte, this).setVisible(true);
            System.exit(1);
        }
        desastreImageRevolte = new JLabel(image);
        desastreImageRevolte.setBounds(33, 32, image.getIconWidth(), image.getIconHeight());
        add(desastreImageRevolte);

        image = GraphicsHelper.getImageIcon(GraphicsParameters.pathDesastreVide, this);
        if (image.getIconHeight() == -1) {
            GraphicsHelper.afficherErreur("Erreur", "Erreur lors de l'ouverture du fichier image : " + GraphicsParameters.pathDesastreVide, this).setVisible(true);
            System.exit(1);
        }
        desastreImageVide = new JLabel(image);
        desastreImageVide.setBounds(33, 32, image.getIconWidth(), image.getIconHeight());
        add(desastreImageVide);

        font = GraphicsHelper.getFont(16, "bold");
        desastreLabel = new JLabel();
        desastreLabel.setFont(font);
        desastreLabel.setHorizontalAlignment(SwingConstants.CENTER);
        desastreLabel.setBounds(33, 50, largeur - 66, hauteurLabel * 2);
        add(desastreLabel);

        famineLabel = new JLabel();
        famineLabel.setFont(font);
        famineLabel.setBounds(50, GraphicsParameters.smallFrameTopY + 10, largeur - 50, hauteurLabel);
        add(famineLabel);
    }

    public void majInterface() {
        desastreImageSecheresse.setVisible(false);
        desastreImagePeste.setVisible(false);
        desastreImageRevolte.setVisible(false);
        desastreImageInvasion.setVisible(false);
        desastreImageVide.setVisible(false);

        for (Component c : getComponents()) {
            if (c instanceof FamineJLabel) {
                remove(c);
            }
        }

        if (mode == MODE_SELECTION) {
            ouvrierLabel.setVisible(true);
            nourritureLabel.setVisible(true);
            instructionLabel.setVisible(true);
            resFoodLabel.setVisible(true);
            resOuvLabel.setVisible(true);
            infosLabel.setVisible(true);

            int nbNecessaire = (nbVille - (nbNourriture + nbNourritureSel));
            StringBuilder msg = new StringBuilder();

            if (nbNecessaire <= 0) {
                msg.append("Vous avez suffisamment de nourriture pour nourrir vos villes.");
            } else {
                msg.append("Il vous faut encore ");
                msg.append(nbNecessaire);
                if (nbNecessaire > 1) {
                    msg.append(" nourritures");
                } else {
                    msg.append(" nourriture");
                }
                msg.append(" pour nourrir vos villes.");
            }

            infosLabel.setText(msg.toString());

            ouvrierLabel.setText(String.valueOf(nbOuvrier + nbOuvrierSel));
            nourritureLabel.setText(String.valueOf(nbNourriture + nbNourritureSel));

            int x = 0;
            int y = 0;
            int espace = 5;

            for (int i = 0; i < nbChoix; i++) {
                SelectionDeJPanel sel = new SelectionDeJPanel(controller);
                if (i == 0) {
                    x = (largeur - sel.getLargeur()) / 2;
                    y = (400 - (sel.getHauteur() + espace) * nbChoix) / 2;
                }

                GraphicsHelper.setBounds(x, y, sel);
                sel.getNourritureJButton().addActionListener(this);
                sel.getOuvrierJButton().addActionListener(this);
                add(sel);

                selectionDeListe.add(sel);
                y += sel.getHauteur() + espace;
            }
        } else if (mode == MODE_INFOS_ALIMENTATION) {
            String text = "";
            if (desastre != null) {

                text = "<html><center>" + desastre.getDescription() + "</center></html>";

                if (desastre instanceof Invasion) {
                    desastreImageInvasion.setVisible(true);
                }
                if (desastre instanceof Peste) {
                    desastreImagePeste.setVisible(true);
                }
                if (desastre instanceof Secheresse) {
                    desastreImageSecheresse.setVisible(true);
                }
                if (desastre instanceof Revolte) {
                    desastreImageRevolte.setVisible(true);
                }

                desastreLabel.setForeground(Color.WHITE);

            } else {
                text = "Vous n'avez pas subit de désastre.";
                desastreLabel.setForeground(Color.WHITE);
                desastreImageVide.setVisible(true);
            }

            desastreLabel.setText(text);
            desastreLabel.setVisible(true);

            if (nbVillesFamine == 0) {
                text = "";
                famineLabel.setForeground(Color.WHITE);
            } else if (nbVillesFamine == 1) {
                text = "1 ville a subi la famine.";
                famineLabel.setForeground(Color.RED);
            } else {
                text = nbVillesFamine + " villes ont subi la famine.";
                famineLabel.setForeground(Color.RED);
            }

            int x = 40;
            int y = GraphicsParameters.smallFrameTopY + 40;
            for (int i = 0; i < nbVillesFamine; i++) {
                FamineJLabel label = new FamineJLabel();
                label.setBounds(x, y, label.getImage().getIconWidth(), label.getImage().getIconHeight());
                add(label);
                x += label.getImage().getIconWidth() + 5;
            }

            famineLabel.setText(text);
            famineLabel.setVisible(true);
        }

        repaint();
    }

    public void reset(int modeAffichage) {
        mode = modeAffichage;

        nbNourritureSel = 0;
        nbOuvrierSel = 0;
        nbVille = controller.getNbVilleJoueurCourant();

        instructionLabel.setVisible(false);
        resFoodLabel.setVisible(false);
        resOuvLabel.setVisible(false);

        desastreLabel.setText("");
        desastreLabel.setVisible(false);
        famineLabel.setText("");
        famineLabel.setVisible(false);

        infosLabel.setText("");
        infosLabel.setVisible(false);
        ouvrierLabel.setText("0");
        ouvrierLabel.setVisible(false);
        nourritureLabel.setText("0");
        nourritureLabel.setVisible(false);

        if (selectionDeListe != null) {
            for (SelectionDeJPanel sel : selectionDeListe) {
                remove(sel);
            }
        }

        selectionDeListe = new ArrayList<SelectionDeJPanel>();

        majInterface();
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() instanceof NourritureJButton) {
            NourritureJButton button = (NourritureJButton) e.getSource();
            SelectionDeJPanel selPanel = (SelectionDeJPanel) button.getParent();

            nbNourritureSel += nbNourritureSup;
            if (!selPanel.getOuvrierJButton().isEnabled()) {
                nbOuvrierSel -= nbOuvrierSup;
                selPanel.getOuvrierJButton().setEnabled(true);
            }
            button.setEnabled(false);

            majInterface();

        } else if (e.getSource() instanceof OuvrierJButton) {
            OuvrierJButton button = (OuvrierJButton) e.getSource();
            SelectionDeJPanel selPanel = (SelectionDeJPanel) button.getParent();

            nbOuvrierSel += nbOuvrierSup;
            if (!selPanel.getNourritureJButton().isEnabled()) {
                nbNourritureSel -= nbNourritureSup;
                selPanel.getNourritureJButton().setEnabled(true);
            }
            button.setEnabled(false);

            majInterface();
        } else if (e.getSource() == etapeSuivante) {
            if (mode == MODE_SELECTION) {
                int delta = nbChoix - (nbOuvrierSel / nbOuvrierSup + nbNourritureSel / nbNourritureSup);
                if (delta != 0) {
                    GraphicsHelper.afficherErreur("Sélection des ouvriers/nourritures", "Il vous reste " + delta + " choix à faire.", this).setVisible(true);
                } else {
                    controller.nourrirVilles(nbOuvrierSel, nbNourritureSel);
                    controller.resoudreDesastres();
                    controller.etapeSuivante();
                }
            } else if (mode == MODE_INFOS_ALIMENTATION) {
                controller.etapeSuivante();
            }
        }
    }

    @Override
    public void nourritureChanged(int nbNourriture) {
        this.nbNourriture = nbNourriture;
    }

    @Override
    public void ouvrierChanged(int nbOuvrier) {
        this.nbOuvrier = nbOuvrier;
    }

    public void desGardesChanged(ArrayList<TypeDes> listeDes) {
        nbChoix = 0;
        for (TypeDes de : listeDes) {
            if (de == TypeDes.TRAVAILLEURSNOURRITURE) {
                nbChoix++;
            }
        }
    }

    public void desastreSuffered(Desastre desastre) {
        this.desastre = desastre;
    }

    public void famineSuffered(int nbVille) {
        nbVillesFamine = nbVille;
    }

    @Override
    public void listeDeveloppementChanged(ArrayList<Developpement> listeDeveloppement) {
        nbNourritureSup = 2;
        nbOuvrierSup = 2;
        for (Developpement dev : listeDeveloppement) {
            if (dev instanceof Maconnerie) {
                nbOuvrierSup = 3;
            }
            if (dev instanceof Agriculture) {
                nbNourritureSup = 3;
            }
        }
    }
}
